xlv.obj.tree={
	extend:function(){
		this.extend('xlv.obj.ulli');
	},	
	implement:function(){
	},
	create:function(tag){
		var div=document.createElement((tag||'div'));
		div.setAttribute('xlvobject','xlv.obj.tree');
		Element.addClassName(div,'class_tree');
		return div;			
	},
	properties:{
		handleHeight:25,
		handleWidth:18,
		effect:true,
		editable:true,
		dmName:null,
		dmPath:null,
		handleLine:true
	},
	method:{
		initial:function(){
			this.$super('xlv.obj.ulli.initial');
			Element.addClassName(this,'class_tree');
			this.addEventHandler('mousedown', '_mousedown_tree',this.$V.rootUL);
			this.addEventHandler('dblclick', '_dblclick',this.$V.rootUL);
			if(this.$V.rootUL) {
				Element.addClassName(this.$V.rootUL,'tree_root');
				this._runtimeStyle(this.$V.rootUL);
			}
		},
		updateStyle:function(tree_node){
			var a=xlv.util.ancestors(tree_node,{tag:'ul'},{object:this});
			for(var i=0,n=a.length;i<n && i<2;++i)this._runtimeStyle(a[i],true);
			a=[tree_node];
			a.push(xlv.util.findPrevSibling(tree_node,{tag:'li'}));
			a.push(xlv.util.findNextSibling(tree_node,{tag:'li'}));
			for(var i=0,n=a.length,u;i<n;++i){
				if(a[i]&&(u=xlv.util.findDirectChild(a[i],{tag:'ul'})))this._runtimeStyle(u,true);
			}
		},
		toggle:function(tree_node){
			tree_node=(tree_node||this.select_getSelected());
			this.expand(tree_node,!this.isExpanded(tree_node));
		},
		isExpanded:function(tree_node){
			tree_node=(tree_node||this.select_getSelected());
			var ul=xlv.util.findDirectChild(tree_node,{tag:'ul'});
			return(ul&&Element.getStyle(ul,'display')!= 'none');
		},
		expand:function(tree_node,is_expand){
			if(this.$V._effecting)return;
			tree_node=(tree_node||this.select_getSelected());
			var ul=xlv.util.findDirectChild(tree_node,{tag:'ul'});
			if(this.$P.dmName && ul && !ul._created && is_expand){
				var indexes=xlv.util.indexesForLI(tree_node);
				var dm=this.mvc_getModel();
				var node=dm.getNode(xlv.util.indexesToXPath(indexes),this._getRootNode(dm));
				this._createLIforChildren(dm,node,ul);
				ul._created=true;
			}
			if(ul){
				if(this.$P.effect){
					var effect={element:ul};
					var save_overflow=ul.style.overflow;
					if(is_expand){
						ul.style.display='none';
						ul.style.height='auto';
						var dim=Element.getDimensions(ul);
						ul.style.height='0px';
						ul.style.display='block';
						effect.style={height:dim.height};
						effect.finished=(function(){
							effect.element.style.display='block';
							effect.element.style.height='';
							effect.element.style.overflow=save_overflow;
							this._runtimeStyle(effect.element);
							this.$V._effecting=false;
						}).bind(this);
					}else{
						effect.style={height:0};
						effect.finished=(function(){
							effect.element.style.display='none';
							effect.element.style.height='';
							effect.element.style.overflow=save_overflow;
							this.$V._effecting=false;
						}).bind(this);
					}
					ul.style.overflow='hidden';
					this.$V._effecting=true;
					xlv.util.styleEffect(effect);
				}else Element.setStyle(ul,{display:(is_expand)?'block':'none'});
				var id=tree_node.id;
				id=(is_expand)?id.replace(/\B_p/i, '_m'):id.replace(/\B_m/i, '_p');
				tree_node.setAttribute('id', id);
				this._runtimeStyle(ul);
			}
		},
		expandAll:function(is_expand){
			var children=xlv.util.children(this.$V.rootUL,{tag:'li'});
			for(var i=0;i<children.length;++i)this.expand(children[i],is_expand);
		},
		_runtimeStyle:function(ul,refresh){
			if(ul._styled&&!refresh) return;
			ul._styled=null;
			if(Element.getStyle(ul,'display')=='none')return;
			var li=xlv.util.findParent(ul,{tag:'li'},{tag:'ul'});
			if(!xlv.util.findNextSibling(li,{tag:'li'})||!this.$P.handleLine)
				 Element.removeClassName(ul,'tree_handleLine');
			else Element.addClassName(ul,'tree_handleLine');
			
			var root=xlv.util.levelOfDescendant(this,ul,{tag:'ul'})==1;
			var lis=xlv.util.children(ul,{tag:'li'});
			for(var i=0,n=lis.length;i<n;++i){
				var child_ul=xlv.util.findDirectChild(lis[i],{tag:'ul'});
				var visible=(child_ul)? Element.getStyle(child_ul,'display')!='none':false;
				var id='xlvid_tree';
				if(this.$P.handleLine) {
					id += (child_ul) ? (visible) ? '_m' : '_p' : '_n';
					id += (i==lis.length-1) ? '_0' :'_1';
					id += (i==0 && root) ? '_r' :'';
				}
				else id =(child_ul)?(visible)?'_m':'_p':'_b';
				if(child_ul&&!visible){
					var dim=Element.getDimensions(lis[i]);
					if(dim.height>0){
						var pos='0px '+((dim.height-this.$P.handleHeight)/2)+'px';
						Element.setStyle(lis[i],{backgroundPosition:pos});
					}
				}
				lis[i].setAttribute('id',id);
			}
			ul._styled=true;	
		},
		_mousedown_tree:function(event){
			var target=event.target;
			if(xlv.util.isTag(target, 'li')){
				var ul=xlv.util.findDirectChild(target,{tag:'ul'});
				if(ul) {
					var pos=Element.getStyle(target, 'background-position');
					pos=(pos)? pos.split(' '):[0,0];
					var dim=[target.offsetLeft,target.offsetTop];
					dim[0]+=this.$P.handleWidth;
					dim[1]+=this.$P.handleHeight+parseInt(pos[1])*2;
					if((event.offsetX||event.layerX)>dim[0]||(event.offsetY||event.layerY)>dim[1]) return;
					this.toggle(target);
				}
			}
		},
		_dblclick:function(event){
			var li=this.select_selectable(event.target);
			if(li && li==this.select_getSelected())	this.toggle(li);
		}
	}
};
